<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>js 运动--多物体运动</title>
    <style type="text/css">
.div1{
    width: 100px;
    height: 100px;
    background-color: #99CCFF;
    margin:10px;
}
.div2{
    width: 100px;
    height: 100px;
    background-color: red;
    margin:10px;
    float:left;
    filter:alpha(opacity:30);
    opacity: 0.3;
}
.div3{
    width: 100px;
    height: 100px;
    background-color: #99CCFF;
    margin:10px;
    float: left;
    border: 10px solid #6699CC;
}
.div4{
    width: 100px;
    height: 100px;
    background-color: yellow;
    margin:10px;
    border: 10px solid black;
    filter:alpha(opacity:30);
    opacity: 0.3;
}
.clear{
    clear: both;
}
    </style>
</head>
<body>

<h2>1、多物体同时运动</h2>
<div class="div1"></div>
<div class="div1"></div>
<div class="div1"></div>

<h2>2、多物体淡入淡出</h2>
<div class="div2"></div>
<div class="div2"></div>
<div class="div2"></div>
<div class="clear"></div>

<h2>3、变高和变宽--offsetWidth,offsetHeight问题</h2>
<div class="div3"></div>
<div class="div3"></div>
<div class="clear"></div>

<h2>3、变高和变宽--解决（可以传入任意值的运动框架）</h2>
<div class="div3"></div>
<div class="div3"></div>
<div class="clear"></div>

<h2>4、用上述框架实现淡入淡出--问题</h2>
opacity:<input type="text" id="txt4">
<div class="div4"></div>
<script>

window.onload = function(){

    var aDiv1 = getByClass(document, "div1");
    var aDiv2 = getByClass(document, "div2");
    var aDiv3 = getByClass(document, "div3");
    var aDiv4 = getByClass(document, "div4");

    // 1、多物体同时运动
    for(var i=0; i<aDiv1.length; i++){
        // 给div加一个自定义定时器属性
        aDiv1[i].timer = null;    
        aDiv1[i].onmouseover = function(){
            startMove1(this, 200);
        }
        aDiv1[i].onmouseout = function(){
            startMove1(this, 100);
        }
    }

    // 2、多物体淡入淡出
    for(var i=0; i<aDiv2.length; i++){
        aDiv2[i].timer = null;    
        // 给div加一个自定义alpha属性
        aDiv2[i].alpha = 30; 
        aDiv2[i].onmouseover = function(){
            startMove2(this, 100);
        }
        aDiv2[i].onmouseout = function(){
            startMove2(this, 30);
        }
    }

    // 3、变高和变宽--问题
    aDiv3[0].onmouseover = function(){
        startMove3_h(this, 200);
    }
    aDiv3[0].onmouseout = function(){
        startMove3_h(this, 100);
    }
    aDiv3[1].onmouseover = function(){
        startMove3_w(this, 200);
    }
    aDiv3[1].onmouseout = function(){
        startMove3_w(this, 100);
    }
    // 3、变高和变宽--解决
    aDiv3[2].onmouseover = function(){
        startMove3(this, 'height', 200);
    }
    aDiv3[2].onmouseout = function(){
        startMove3(this, 'height', 100);
    }
    aDiv3[3].onmouseover = function(){
        startMove3(this, 'width', 200);
    }
    aDiv3[3].onmouseout = function(){
        startMove3(this, 'width', 100);
    }


    // 4、用上述框架实现淡入淡出--问题
    aDiv4[0].onmouseover = function(){
        startMove4(this, 'opacity', 100);
    }
    aDiv4[0].onmouseout = function(){
        startMove4(this, 'opacity', 30);
    }
}


// 1、多物体同时运动-----------------------------------------------------------------------------
// 问题：单定时器
// 解决：让每个div都有一个定时器
/*var timer1 = 0;
function startMove1(obj, iTarget){
    clearInterval(timer1);
    timer1 = setInterval(function(){
        var speed = (iTarget - obj.offsetWidth)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(obj.offsetWidth == iTarget){
            clearInterval(timer1);
        }
        else{
            obj.style.width = obj.offsetWidth + speed + 'px';
        }
    },30);
}*/
function startMove1(obj, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget - obj.offsetWidth)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(obj.offsetWidth == iTarget){
            clearInterval(obj.timer);
        }
        else{
            obj.style.width = obj.offsetWidth + speed + 'px';
        }
    },30);
}




// 2、多物体淡入淡出----------------------------------------------------------------------
// 问题：alpha公用（经验：在多物体运动中，所有东西都不能公用）
// 解决，让每个div有一个alpha属性
/*var alpha = 30;
function startMove2(obj, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget - alpha)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(alpha == iTarget){
            clearInterval(obj.timer);
        }else{
            alpha += speed;
            obj.style.filter = "alpha(opacity:"+alpha+")";
            obj.style.opacity = alpha/100;
        }
    }, 30);
}*/


function startMove2(obj, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget - obj.alpha)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(obj.alpha == iTarget){
            clearInterval(obj.timer);
        }else{
            obj.alpha += speed;
            obj.style.filter = "alpha(opacity:"+obj.alpha+")";
            obj.style.opacity = obj.alpha/100;
        }
    }, 30);
}




// 3、变高和变宽------------------------------------------------------------------------
// 问题：代码重复
// 潜在问题：offsetWidht, offsetHeight （width+border+padding）
// 就是说如果盒子存在border或padding, 会出现问题
function startMove3_h(obj, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget - obj.offsetHeight)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(obj.offsetHeight == iTarget){
            clearInterval(obj.timer);
        }else{
           obj.style.height = obj.offsetHeight + speed + 'px';
        }
    }, 30);
}

function startMove3_w(obj, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget - obj.offsetWidth)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(obj.offsetWidth == iTarget){
            clearInterval(obj.timer);
        }else{
           obj.style.width = obj.offsetWidth + speed + 'px';
        }
    }, 30);
}


// 解决：
// 给函数再添加一个变量attr; 
// 不用offsetWidth, 获取行间样式width来操作运动;
// startMove3--可以传入任意值的运动框架
function startMove3(obj, attr, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var val = parseInt(getStyle(obj, attr));
        var speed = (iTarget - val)/6;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(val == iTarget){
            clearInterval(obj.timer);
        }else{
           obj.style[attr] = val + speed + 'px';
        }
    }, 30);
}



// 多物体运动框架
// 定时器作为物体的属性
// 参数：物体，目标值
// 例子：多个Div淡入淡出
// 所有东西都不能公用
// 属性与运动对象绑定：速度，其他属性值（如透明度）


// 4、用上述框架实现淡入淡出--问题----------------------------------------
// 问题1：startMove3里的parseInt会把opacity的值转为整数
// 问题2：obj.style[attr] = height + speed + 'px';   opacity没有px
function startMove4(obj, attr, iTarget){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var val = 0;
        if(attr == 'opacity'){
            // getStyle(obj, attr)对于opacity, chrome ie返回的都是小数
            // val = parseFloat(getStyle(obj, attr))*100;
            // 这里如果不用Math.round会有问题，注意txt4的value
            val = Math.round(parseFloat(getStyle(obj, attr))*100);
        }else{
            val = parseInt(getStyle(obj, attr));
        }
        
        var speed = (iTarget - val)/5;
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
        if(val == iTarget){
            clearInterval(obj.timer);
        }else{
            if(attr == 'opacity'){
                obj.style.filter = 'alpha(opacity:'+(val + speed)+')';
                obj.style.opacity = (val + speed)/100;
                document.getElementById("txt4").value = obj.style.opacity;
            }else{
                obj.style[attr] = val + speed + 'px';
            }
        }
    }, 30);
}






// 公用函数---------------------------------------------------------------

// 获取非行间样式
function getStyle(obj, name){
    if(obj.currentStyle){
        return obj.currentStyle[name];
    }
    else{
        return getComputedStyle(obj, null)[name];
    }
}

function getByClass(oParent, sClass){
    var aResult = [];
    var aEle = oParent.getElementsByTagName("*");
    for(var i=0; i<aEle.length; i++){
        if(aEle[i].className === sClass){
            aResult.push(aEle[i]);
        }
    }
    return aResult;
}


</script>
</body>
</html>